package com.innerchic.mapper.app;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.innerchic.mapper.log.Logger;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

/**
 * ================================================
 * 作    者：贾恒飞 >>> 17515250730@163.com
 * 项    目：young
 * 日    期：2021/11/1 16:06
 * 包    名：com.innerchic.mapper.app
 * 描    述：RecyclerView的适配器对象
 * Create by zFox from AndroidStudio4.2
 * ================================================
 */
public abstract class SuperAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    //-------------------------布局管理器相关-------------------------

    /**
     * GridLayoutManager的默认列数
     */
    private int count = 1;

    public void setCount(int count) {
        this.count = count;
    }

    /**
     * 是否使用GridLayoutManager布局管理器,默认使用
     */
    private boolean isSelectGridLayoutManager = true;

    /**
     * 选择垂直布局管理器
     */
    public void selectLinearLayoutManager() {
        isSelectGridLayoutManager = false;
    }

    /**
     * 选择网格布局管理器
     */
    public void selectGridLayoutManager() {
        isSelectGridLayoutManager = true;
    }

    //-------------------------数据相关操作-------------------------

    /**
     * 当前渲染的数据集合
     */
    protected final List<T> dataContent = new ArrayList<>();

    public void sort(Comparator<? super T> c) {
        if (c == null) return;
        Collections.sort(dataContent, c);
        refreshData();
    }

    /**
     * 拿到当前数据对象
     *
     * @return dataContent
     */
    public List<T> getDataContent() {
        return dataContent;
    }

    /**
     * 重设数据
     * 该操作会清除原数据列表中的所有数据
     *
     * @param initData 数据
     */
    public void resetData(List<T> initData) {
        dataContent.clear();
        if (initData != null) {
            this.dataContent.addAll(initData);
        }
        refreshData();
    }

    /**
     * 追加数据
     * 当前方法调用之后不会刷新页面,需要手动调用刷新
     *
     * @param data 数据
     */
    public void appendData(T data) {
        if (data == null) return;
        dataContent.add(data);
    }

    /**
     * 追加数据并刷新列表
     *
     * @param data 数据
     */
    public void appendAndRefreshData(T data) {
        appendData(data);
        refreshData();
        //滚动到最后一行
        getLayoutManager().scrollToPosition(getItemCount() - 1);
    }

    /**
     * 设置数据
     *
     * @param position 数组下标
     * @param data     数据对象
     * @return true成功
     */
    public boolean updateData(int position, T data) {
        if (position >= dataContent.size()) return false;
        dataContent.set(position, data);
        return true;
    }

    /**
     * 数据筛选接口
     *
     * @param <T> 数据类型
     */
    public interface OnDataFiltering<T> {
        boolean onFilter(T data);
    }

    /**
     * 移除满足条件的项
     * 移除后会自动刷新列表
     *
     * @param onDataFiltering 数据筛选接口
     */
    public void removeIf(OnDataFiltering<T> onDataFiltering) {
        Objects.requireNonNull(onDataFiltering);
        final Iterator<T> each = dataContent.iterator();
        while (each.hasNext()) {
            if (onDataFiltering.onFilter(each.next())) {
                each.remove();
            }
        }
        refreshData();
    }

    /**
     * 数据更新接口
     *
     * @param <T> 数据类型
     */
    public interface OnUpdateDataItem<T> {
        T update(T oldData);
    }


    /**
     * 修改数据
     *
     * @param position       位置
     * @param updateDataItem 数据修改接口
     */
    public void updateData(int position, OnUpdateDataItem<T> updateDataItem) {
        if (position >= dataContent.size() || updateDataItem == null) return;
        T update = updateDataItem.update(dataContent.get(position));
        updateData(position, update);
        refreshData();
    }

    /**
     * 更新状态
     *
     * @param <T> 类型
     */
    public interface OnUpdateStateItem<T> {
        void correct(T data);
    }

    /**
     * 更新状态
     *
     * @param updateStateItem 更新接口
     */
    public void updateState(OnUpdateStateItem<T> updateStateItem) {
        if (updateStateItem == null) return;
        for (T t : dataContent) {
            updateStateItem.correct(t);
        }
        refreshData();
    }

    /**
     * 移除数据
     *
     * @param data 移除的对象
     */
    public void remove(T data) {
        dataContent.remove(data);
        refreshData();
    }

    /**
     * 获取数据
     *
     * @param position 数据下标
     * @return 对象
     */
    public T getData(int position) {
        return dataContent.get(position);
    }

    /**
     * 移除数据
     *
     * @param position 移除下标
     */
    public void remove(int position) {
        dataContent.remove(position);
        refreshData();
    }

    /**
     * 清理数据 并刷新页面
     */
    public void clearData() {
        resetData(null);
    }

    /**
     * 把数据插入初始位置
     *
     * @param data 数据
     */
    public void insertInitialData(T data) {
        insertData(data, 0);
    }

    /**
     * 插入数据
     *
     * @param data     数据
     * @param position 插入的位置,如果大于长度则追加在末尾
     */
    public void insertData(T data, int position) {
        if (position >= dataContent.size()) {
            appendData(data);
        } else {
            if (data == null) return;
            dataContent.add(position, data);
        }
        refreshData();
    }

    /**
     * 刷新数据
     */
    public void refreshData() {
        if (mainHandler == null) {
            mainHandler = new Handler(Looper.getMainLooper());
        }
        mainHandler.post(this::notifyDataSetChanged);
    }

    private Handler mainHandler;

    public Handler getMainHandler() {
        return mainHandler;
    }

    //-------------------------布局管理器-------------------------

    /**
     * 当前布局管理器
     */
    private RecyclerView.LayoutManager layoutManager;

    /**
     * 获取布局管理器
     *
     * @return 如果在绑定之前获取则为null
     */
    public RecyclerView.LayoutManager getLayoutManager() {
        return layoutManager;
    }

    /**
     * 资源管理器
     */
    private Resources resources;

    public Resources getResources() {
        return resources;
    }

    /**
     * 绑定布局适配器
     *
     * @param recyclerView 列表组件
     * @param context      上下文关系
     */
    public void bindRecyclerView(RecyclerView recyclerView, Context context) {
        if (recyclerView == null) return;
        if (isSelectGridLayoutManager) {
            layoutManager = new GridLayoutManager(context, count);
        } else {
            layoutManager = new LinearLayoutManager(context);
        }
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(this);
        onCreateIntent = cls -> {
            if (cls == null) return new Intent();
            return new Intent(context, cls);
        };
        resources = context.getResources();
    }

    /**
     * 创建Intent的接口
     */
    private OnCreateIntent onCreateIntent;

    protected interface OnCreateIntent {
        Intent createIntent(Class<? extends SuperActivity> cls);
    }

    /**
     * 创建一个Intent对象
     */
    protected Intent createIntent(Class<? extends SuperActivity> cls) {
        if (onCreateIntent == null) {
            return new Intent(SuperApplication.getApplication(), cls);
        }
        return onCreateIntent.createIntent(cls);
    }

    /**
     * 轻量级的跳转
     *
     * @param intent intent
     */
    public void startActivity(Intent intent) {
        SuperApplication.getApplication().startActivity(intent);
    }

    private View viewRoot;

    public View getViewRoot() {
        return viewRoot;
    }

    //-------------------------适配器实现方法-------------------------

    private Constructor<?> constructor;

    /**
     * 适配器构造方法
     */
    public SuperAdapter() {
        //查找对应的Holder构造对象
        String holderClassName = this.getClass().getName() + "Holder";
        try {
            Class<?> aClass = Class.forName(holderClassName);
            constructor = aClass.getConstructor(View.class);
        } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    private ViewGroup parentGroup;

    protected Context getContext() {
        return parentGroup.getContext();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        parentGroup = parent;
        //获取View对象
        if (hasParent()) {
            ViewGroup parentLayout = parentLayout(parent);
            if (parentLayout == null) {
                viewRoot = LayoutInflater.from(parent.getContext()).inflate(getLayoutRes(viewType), null);
            } else {
                viewRoot = LayoutInflater.from(parent.getContext()).inflate(getLayoutRes(viewType), parentLayout);
            }
        } else {
            viewRoot = LayoutInflater.from(parent.getContext()).inflate(getLayoutRes(viewType), parent, false);
        }
        //尝试获取holder
        RecyclerView.ViewHolder viewHolder = getViewHolder(viewRoot, viewType);
        if (viewHolder != null) return viewHolder;
        try {
            //返回创建对象
            String holderClassName = this.getClass().getName() + "Holder";
            Logger.d("holderClassName:" + holderClassName);
            try {
                Class<?> aClass = Class.forName(holderClassName);
                constructor = aClass.getConstructor(View.class);
            } catch (ClassNotFoundException | NoSuchMethodException e) {
                e.printStackTrace();
            }
            return (RecyclerView.ViewHolder) constructor.newInstance(viewRoot);
        } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }
        //反之返回一个空的viewHolder
        Logger.d("没有合适的适配器对象[" + this.getClass().getName() + "],只能返回空的适配器...");
        return new RecyclerView.ViewHolder(viewRoot) {
        };
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        adapterBindViewHolder(holder, getData(position), position);
    }

    @Override
    public int getItemCount() {
        return dataContent.size();
    }

    //-------------------------监听-------------------------

    /**
     * 项事件处理类
     *
     * @param <T> 泛型
     */
    public interface OnItemMonitorListener<T> {
        void onMonitor(View monitorView, T data, int position, int type);
    }

    /**
     * 默认的监听类
     */
    private OnItemMonitorListener<T> onItemMonitorListener = (monitorView, data, position, type) -> {
    };

    /**
     * 获取监听对象
     */
    protected OnItemMonitorListener<T> getMonitor() {
        return onItemMonitorListener;
    }

    /**
     * 设置监听对象
     */
    public void setItemMonitorListener(OnItemMonitorListener<T> onItemMonitorListener) {
        this.onItemMonitorListener = onItemMonitorListener;
    }

    //-------------------------抽象方法或可重写方法-------------------------

    /**
     * 适配器绑定方法
     *
     * @param holder   适配器视图
     * @param data     当前数据对象
     * @param position 当前索引
     */
    protected abstract void adapterBindViewHolder(RecyclerView.ViewHolder holder, T data, int position);

    /**
     * 方法可重写
     */
    protected RecyclerView.ViewHolder getViewHolder(View view, int viewType) {
        return null;
    }

    /**
     * 是否存在父容器
     *
     * @return 默认false
     */
    protected boolean hasParent() {
        return false;
    }

    /**
     * 父容器布局
     *
     * @param parent
     */
    protected ViewGroup parentLayout(ViewGroup parent) {
        return null;
    }

    /**
     * 获取布局
     *
     * @param viewType 布局类型
     * @return 布局res资源值
     */
    protected abstract @LayoutRes
    int getLayoutRes(int viewType);

}
